// Copyright (c) Microsoft Corporation. All rights reserved.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

namespace Microsoft.TeamFoundation.Migration.VersionControl.Wss
{
    internal class ListItemChangeInfo
    {
        internal List<ListItemInfo> Adds;
        internal List<ListItemInfo> Edits;
        internal List<ListItemInfo> Deletes;
        internal List<RenameListItemInfo> Renames;
    }

    public class ListItemInfo
    {
        public ListItemInfo(row listItem, CultureInfo culture)
        {
            if (listItem == null)
            {
                throw new ArgumentNullException("listItem");
            }
            if (culture == null)
            {
                throw new ArgumentNullException("culture");
            }

            initialize(
                int.Parse(listItem.ows_ID, culture),
                int.Parse(listItem.ows_owshiddenversion, culture),
                extractPrefixedValue(listItem.ows_ID, listItem.ows_FileRef),
                extractPrefixedValue(listItem.ows_ID, listItem.ows_FileLeafRef),
                extractPrefixedValue(listItem.ows_ID, listItem.ows_FileDirRef),
                int.Parse(extractPrefixedValue(listItem.ows_ID, listItem.ows_FSObjType), culture),
                DateTime.Parse(listItem.ows_Modified, culture),
                extractPrefixedValue(null, listItem.ows_Editor),
                0);
        }

        public ListItemInfo(
            int fileId,
            int latestRevision,
            string filePath,
            string fileName,
            string parentPath,
            int fSObjType,
            DateTime modified,
            string editor,
            int previousVersion)
        {
            initialize(fileId, latestRevision, filePath, fileName, parentPath, fSObjType, modified, editor, previousVersion);
        }

        void initialize(
            int fileId,
            int latestRevision,
            string filePath,
            string fileName,
            string parentPath,
            int FSObjType,
            DateTime modified,
            string editor,
            int previousVersion)
        {
            m_fileId = fileId;
            m_latestRevision = latestRevision;
            m_fileName = fileName;
            m_filePath = filePath;
            m_parentPath = parentPath;
            m_FSObjType = FSObjType;
            m_previousVersion = previousVersion;
            m_editor = editor;
            m_modified = modified;
        }

        public int FileId
        {
            get
            {
                return m_fileId;
            }
        }

        public int LatestRevision
        {
            get
            {
                return m_latestRevision;
            }
        }

        public string FileName
        {
            get
            {
                return m_fileName;
            }
        }

        public string FilePath
        {
            get
            {
                return m_filePath;
            }
        }

        public string ParentPath
        {
            get
            {
                return m_parentPath;
            }
        }

        public int PreviousVersion
        {
            get
            {
                return m_previousVersion;
            }
        }

        public int FSObjType
        {
            get
            {
                return m_FSObjType;
            }
        }

        public string Editor
        {
            get
            {
                return m_editor;
            }
        }

        public DateTime Modified
        {
            get
            {
                return m_modified;
            }
        }

        int m_fileId;
        int m_latestRevision;
        string m_filePath;
        string m_fileName;
        string m_parentPath;
        int m_previousVersion;
        int m_FSObjType;
        string m_editor;
        DateTime m_modified;


        private static string extractPrefixedValue(string prefix, string prefixedString)
        {
            // <prefix>;#<value> - we want <value>
            
            if (prefix == null) // prefix can't be decided
            {
                int prefixIndex = prefixedString.IndexOf(";#");

                if (prefixIndex < 0)
                {
                    throw new ArgumentException(WSS2TFSResources.StringNoPrefix);
                }
                return prefixedString.Substring(prefixIndex + 2);
            }
            else
            {
                if (prefixedString.Length < (prefix.Length + 2)) // <prefix>;#
                {
                    throw new ArgumentException(WSS2TFSResources.StringNoPrefix);
                }

                if (!prefixedString.StartsWith(prefix + ";#"))
                {
                    throw new ArgumentException(WSS2TFSResources.StringNoPrefix);
                }

                return prefixedString.Substring(prefix.Length + 2);
            }
        }
    }

    public class RenameListItemInfo : ListItemInfo
    {
        internal RenameListItemInfo(
            int fileId,
            int latestRevision,
            string filePath,
            string fileName,
            string parentPath,
            int FSObjType,
            DateTime modified,
            string editor,
            int previousVersion,
            string oldFilePath,
            string oldFileName,
            string oldParentPath)
            : base(fileId, latestRevision, filePath, fileName, parentPath, FSObjType, modified, editor, previousVersion)
        {
            m_oldFilePath = oldFilePath;
            m_oldFileName = oldFileName;
            m_oldParentPath = oldParentPath;
        }

        public string OldFileName
        {
            get
            {
                return m_oldFileName;
            }
        }

        public string OldFilePath
        {
            get
            {
                return m_oldFilePath;
            }
        }

        public string OldParentPath
        {
            get
            {
                return m_oldParentPath;
            }
        }

        string m_oldFilePath;
        string m_oldFileName;
        string m_oldParentPath;

    }
}
